package com.feidee.data.report.util.threadutil;

import com.alibaba.fastjson.JSON;
import com.feidee.data.report.constant.Constant;
import com.feidee.data.report.model.MonitorReportModel;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 为数据门户运行提供统一的线程池服务
 */
public class ThreadPoolUtil {

	private static ExecutorService reportExecThreadPool = Executors.newFixedThreadPool(Constant.EXEC_THREAD_POOL_SIZE);
	private static ExecutorService reportMonitorThreadPool = Executors.newFixedThreadPool(Constant.MONITOR_THREAD_POOL_SIZE);
	private static Map<String, MonitorReportModel> reportExecInfoCache = new ConcurrentHashMap<String, MonitorReportModel>();

	/**
	 * 提交Callable类型的线程到执行线程池
	 * @param thread
	 */
	public static void submitReportExecTask(Callable<Integer> thread) {

		reportExecThreadPool.submit(thread);
	}

	/**
	 * 提交Runnable类型的线程到执行线程池
	 * @param thread
	 */
	public static Future<?> submitReportExecTask(Runnable thread) {

		return reportExecThreadPool.submit(thread);
	}

	/**
	 * 提交Callable类型的线程到执行线程池，该种提交方式会触发监控
	 * @param groupName
	 * @param threadList
	 * @return
	 */
	public static String submitReportExecTask(String groupName, List<Callable<Integer>> threadList) {

		MonitorReportModel monitorReportModel = new MonitorReportModel();
		monitorReportModel.setAtomicInteger(new AtomicInteger(0));
		monitorReportModel.setSuccessMap(new ConcurrentHashMap<String, Long>());
		monitorReportModel.setExceptionMap(new ConcurrentHashMap<String, Long>());
		reportExecInfoCache.put(groupName, monitorReportModel);

		for (Callable<Integer> thread : threadList) {
			reportExecThreadPool.submit(thread);
		}

		return groupName;
	}

	/**
	 * 提交监控线程到监控线程池
	 * @param thread
	 */
	public static void submitReportMonitorTask(Runnable thread) {

		reportMonitorThreadPool.submit(thread);
	}

	/**
	 * 获取一组报表已经执行完成的线程数
	 * @param groupName
	 * @return
	 */
	public static int threadCompletedCnt(String groupName) {

		MonitorReportModel monitorReportModel = reportExecInfoCache.get(groupName);
		if (null == monitorReportModel) {
			return 0;
		}

		return monitorReportModel.getAtomicInteger().get();
	}

	/**
	 * 获取报表执行成功的记录
	 * @param groupName
	 * @return
	 */
	public static Map<String, Long> threadSuccessReport(String groupName) {

		MonitorReportModel monitorReportModel = reportExecInfoCache.get(groupName);
		if (null == monitorReportModel) {
			return new HashMap<String, Long>();
		}
		return monitorReportModel.getSuccessMap();
	}

	/**
	 * 获取报表执行异常的记录
	 * @param groupName
	 * @return
	 */
	public static Map<String, Long> threadExceptionReport(String groupName) {

		MonitorReportModel monitorReportModel = reportExecInfoCache.get(groupName);
		if (null == monitorReportModel) {
			return new HashMap<String, Long>();
		}
		return monitorReportModel.getExceptionMap();

	}

	/**
	 * 将报表执行线程完成统计加1，每个线程执行完都应该加1
	 * @param groupName
	 */
	public static void addThreadSuccessCnt(String groupName) {

		MonitorReportModel monitorReportModel = reportExecInfoCache.get(groupName);
		if (null != monitorReportModel) {
			monitorReportModel.getAtomicInteger().getAndIncrement();
		}
	}

	/**
	 * 请求报表对应的运行缓存信息
	 * @param groupName
	 */
	public static void deleteReportInfoCache(String groupName) {

		reportExecInfoCache.remove(groupName);
	}

	/**
	 * 获取唯一的ID
	 * @return
	 */
	public static String getUuid() {

		return UUID.randomUUID().toString().replace("-", "");

	}

	/**
	 * 往监控报表记录中添加执行成功的报表
	 * @param name
	 * @param reportStatusStr
	 * @param reportIndex
	 */
	public static void addExecSuccessReport(String name, String reportStatusStr, long reportIndex) {

		MonitorReportModel monitorReportModel = reportExecInfoCache.get(name);
		if (null != monitorReportModel) {
			Map<String, Long> successMap = monitorReportModel.getSuccessMap();
			successMap.put(reportStatusStr, reportIndex);
		}
	}

	/**
	 * 往监控报表记录中添加执行失败的报表
	 * @param name
	 * @param reportStatusStr
	 * @param reportIndex
	 */
	public static void addExecExceptionReport(String name, String reportStatusStr, long reportIndex) {

		MonitorReportModel monitorReportModel = reportExecInfoCache.get(name);
		if (null != monitorReportModel) {
			Map<String, Long> exceptionMap = monitorReportModel.getExceptionMap();
			exceptionMap.put(reportStatusStr, reportIndex);
		}
	}

	/**
	 * 获取门户当前运行报表执行状态信息
	 * @return
	 */
	public static String dataReportRunInfoCache() {

		return JSON.toJSONString(reportExecInfoCache);
	}

}
